/*******************************************************************************
* Copyright (c) 2012 
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* zhangliang - initial API and implementation
*******************************************************************************/

#ifndef DEST_CACHE_H
#define DEST_CACHE_H

#include "handle.h"
#include "singleton.h"

/*!
 * @brief
 *  destination infomation cache, sync with every servers
 * @note
 *  this cache is modify by a module which communicate with daemon process
 *  and the daemon process is sync with centre dns server
 *  TODO: mutex can be replace by rwlock
 */
class DestCache : public Singleton<DestCache> {
 public:
  /*!
   * @brief
   *  init, launch '.cache' module 
   *  upload current server id/addr, and get other servers' id/addr 
   */
  void Init(void);

  /*!
   * @brief
   *  update record, called by '.cache' module
   * @note
   *  raw_list format:
   *  list_size(u16) |
   *  is_add(u16)|key_size(u16)|key(str)|val_size(u16)|val(str)
   *  ...
   *  note that 'val' part is not exist if !is_add
   */
  void UpdateRecord(const char* raw_list);
  void UpdateRecord(uint16_t is_add, const char* key, const char* val);

  /*!
   * @brief
   *  add service name request according to name type(local/unnamed/public)
   */
  void RegisterService(const std::string& name, Handle handle);

  /*!
   * @brief
   *  remove service according to name type(local/unnamed/public)
   */
  void RetireService(const std::string& name);

  /*!
   * @brief
   *  query handle by name
   */
  Handle Query(const std::string& name);

  /*!
   * @brief
   *  query addr by svr id
   */
  std::string Query(uint32_t svr_id);

 private:
  // map string -> string
  // cache includes two type of infomation:
  // 1. name -> handle
  // 2. svr id -> addr
  // for the sake of 'simplicity' as cuikehong said, these two kind of info
  // is merge into one, everything is stringify, so be it
  boost::unordered_map<std::string, std::string> cache_;
  boost::mutex cache_mutex_;
  boost::unordered_map<std::string, Handle> local_services_;
  boost::mutex local_services_mutex_;
  Handle module_handle_;
};

#endif // DEST_CACHE_H

